package microframe.event
{
	import flash.events.EventDispatcher;
	import flash.events.IEventDispatcher;
	import flash.utils.Dictionary;
	
	/**
	 * @author winnie
	 */	
	public class MicroEventObserver extends EventDispatcher
	{
		
		private static var _instance : MicroEventObserver;
		private static var _dicListenerList : Dictionary = new Dictionary( true );
		
		
		/**
		 * @return [읽기 전용] 이벤트 직접 청취 및 직접 전달 자. 
		 */		
		public static function get instance():MicroEventObserver
		{
			if( _instance == null ) _instance = new MicroEventObserver();
			return _instance;
		}
		
		
		
		/**
		 * @param type 해당 이벤트에 대한 청취자 등록
		 * @param fn 이벤트 함수
		 */		
		public static function registListener( type:String, fn:Function ):void
		{
			if( _dicListenerList[ type ] == null )
			{
				_dicListenerList[ type ] = new Vector.<Function>();
			}
			
			checkAndRigist( type, fn );
		}
		
		
		
		// 이벤트 타입에 따른 리스트 체크 및 추가
		private static function checkAndRigist( type:String, fn:Function ):void
		{
			var len:int = _dicListenerList[ type ].length;
			for (var i:int = 0; i < len; i++) 
			{
				if( _dicListenerList[ type ][i] == fn ) return;
			}
			
			_dicListenerList[ type ].push( fn );
		}
		
		
		
		
		
		
		/**
		 * @param type 에 등록된 리스너 실행
		 */		
		public static function executeListener( type:String ):void
		{
			if( _dicListenerList[ type ] != null )
			{
				var len:int = _dicListenerList[ type ].length;
				for (var i:int = 0; i < len; i++) 
				{
					// 만약 excute 와 remove 를 동시에 하게 되면 간혹 length 는 있는데 내용이 undefined 로 뜨는경우가 있다.
					if( _dicListenerList[ type ].length > i ) _dicListenerList[ type ][i]();
				}
			}
		}
		
		
		/**
		 * @param type 해당 이벤트에 대한 청취자 제거
		 * @param fn 제거하려는 함수명
		 */		
		public static function removeListener( type:String, fn:Function ):void
		{
			var tempFn : Function;
			if( _dicListenerList[ type ] != null )
			{
				var len:int = _dicListenerList[ type ].length;
				for (var i:int = 0; i < len; i++) 
				{
					if( _dicListenerList[ type ][i] == fn )
					{
						delete( _dicListenerList[ type ].splice( _dicListenerList[ type ].indexOf( _dicListenerList[ type ][i] ) , 1 ) );
						return;
					}
				}
			}
		}
		
		
		/*
		// 등록된 리스너 trace
		public static function tracefn(type:String):void
		{
			var len:int = _dicListenerList[ type ].length;
			for (var i:int = 0; i < len; i++) 
			{
				trace(" ==> MicroEventObserver tracefn : " + _dicListenerList[ type ][i]);
			}
		}
		*/
		
		
		/**
		 * @param target
		 */		
		public function MicroEventObserver(target:IEventDispatcher=null)
		{
			super(target);
		}
	}
}